user: Please show me the C implementation that matches the assembly code listed below:

```asm
<improved_bubblesort>:
  endbr64
  push   %r15
  xor    %eax,%eax
  push   %r14
  mov    %esi,%r14d
  push   %r13
  mov    %rdi,%r13
  lea    D24(%rip),%rdi
  push   %r12
  mov    %r13,%r15
  lea    D44(%rip),%r12
  push   %rbp
  lea    0x14(%r13),%rbp
  push   %rbx
  mov    %r13,%rbx
  sub    $0x8,%rsp
  call   <printf@plt>
  lea    D33(%rip),%rdi
  xor    %eax,%eax
  call   <printf@plt>
L54:
  mov    (%r15),%esi
  mov    %r12,%rdi
  xor    %eax,%eax
  add    $0x4,%r15
  call   <printf@plt>
  cmp    %rbp,%r15
  jne    L54
  lea    -0x1(%r14),%esi
  xor    %r15d,%r15d
  xor    %r14d,%r14d
  test   %esi,%esi
  jle    L16
  xor    %r8d,%r8d
  nopl   0x0(%rax)
L7:
  xor    %edx,%edx
  xor    %edi,%edi
  nopl   0x0(%rax)
L65:
  movq   0x0(%r13,%rdx,4),%xmm0
  pshufd $0xe5,%xmm0,%xmm2
  movd   %xmm0,%ecx
  movd   %xmm2,%eax
  pshufd $0xe1,%xmm0,%xmm1
  cmp    %eax,%ecx
  jle    L47
  movq   %xmm1,0x0(%r13,%rdx,4)
  add    $0x1,%r14d
  mov    $0x1,%edi
L47:
  add    $0x1,%rdx
  cmp    %edx,%esi
  jg     L65
  lea    -0x1(%rsi),%eax
  test   %esi,%esi
  mov    %r8d,%edx
  cmovg  %eax,%edx
  lea    0x1(%r15,%rdx,1),%r15d
  test   %edi,%edi
  je     L16
  mov    %eax,%esi
  test   %eax,%eax
  jne    L7
L16:
  lea    D69(%rip),%rdi
  xor    %eax,%eax
  call   <printf@plt>
L33:
  mov    (%rbx),%esi
  mov    %r12,%rdi
  xor    %eax,%eax
  add    $0x4,%rbx
  call   <printf@plt>
  cmp    %rbp,%rbx
  jne    L33
  mov    %r15d,%esi
  lea    D39(%rip),%rdi
  xor    %eax,%eax
  call   <printf@plt>
  mov    %r14d,%esi
  lea    D42(%rip),%rdi
  xor    %eax,%eax
  call   <printf@plt>
  add    $0x8,%rsp
  lea    D31(%rip),%rdi
  xor    %eax,%eax
  pop    %rbx
  pop    %rbp
  pop    %r12
  pop    %r13
  pop    %r14
  pop    %r15
  jmp    1050 <printf@plt>
```

tool_calls: name: disassemble_data
arguments: label: D24
datatype: string
name: disassemble_data
arguments: label: D44
datatype: string
name: disassemble_data
arguments: label: D33
datatype: string
name: disassemble_data
arguments: label: D69
datatype: string
name: disassemble_data
arguments: label: D39
datatype: string
name: disassemble_data
arguments: label: D42
datatype: string
name: disassemble_data
arguments: label: D31
datatype: string

tool: D24: 

N: %d


tool: D44: %d 

tool: D33: 
Unsorted [First 5]: 

tool: D69: 
Sorted [First 5]: 

tool: D39: 

Comparisons: %d

tool: D42: 
Swaps: %d

tool: D31: 

============================================

assistant: ```c
void improved_bubblesort(int a[], int N) {
  int i, j, temp, compare_ctr = 0, swap_ctr = 0, swapped;
  printf("\n\nN: %d\n", N);
  printf("\nUnsorted [First 5]: ");
  for (i = 0; i < 5; i++) {
    printf("%d ", a[i]);
  }
  for (i = N - 1; i >= 1; i--) {
    swapped = 0;
    for (j = 0; j < i; j++) {
      compare_ctr++;
      if (a[j] > a[j + 1]) {
        temp = a[j + 1];
        a[j + 1] = a[j];
        a[j] = temp;
        swapped = 1;
        swap_ctr++;
      }
    }
    if (swapped == 0) {
      break;
    }
  }
  printf("\nSorted [First 5]: ");
  for (i = 0; i < 5; i++) {
    printf("%d ", a[i]);
  }
  printf("\n\nComparisons: %d", compare_ctr);
  printf("\nSwaps: %d", swap_ctr);
  printf("\n\n============================================");
}
```